#ifndef	__C_VIEWS_REGION_H__
#define	__C_VIEWS_REGION_H__

#ifdef __cplusplus
extern "C" {
#endif

#include "visbsc.h"
#include "vislist.h"

struct view;

typedef struct rect
{
	int left, top;
	int width, height;
}
rect_t;

// rect operations
#define set_rect(r, l, t, w, h) \
do { \
	(r).left = l; \
	(r).top = t; \
	(r).width = w; \
	(r).height = h; \
} while (0)

#define rect_equal(r1, r2) \
	((r1).left == (r2).left && (r1).top == (r2).top \
	&& (r1).width == (r2).width && (r1).height == (r2).height)

#define null_rect(r)		((r).width <= 0 || (r).height <= 0)
#define invalidate_rect(r)	do { (r).width = 0; (r).height = 0; } while (0)

typedef struct rectlist_node
{
	listnode_t ownerlist;
	rect_t r;
}
rectlist_node_t;

// we reuse the rectlist_node allocator
// to allocate this structure so be sure
// to keep the size of this structure
// smaller than rectlist_node
typedef struct region
{
	listnode_t ownerlist;
	listnode_t *rectlist;
	int rect_count;
	struct view* vi;
	uint flags;
	listnode_t head[2];
}
region_t;

// indicate this region is out of date
// and is needed to be updated
#define RGN_FLG_OUT_OF_DATE		(1)

// the following flag is used for
// invalidation operatoin
#define RGN_FLG_PARTIAL			(2)

#define region_isempty(rgn)	(!(rgn).rect_count)
#define region_out_of_date(rgn)	((rgn).flags & RGN_FLG_OUT_OF_DATE)

// export functions
_bool invalidate(struct view* vi, region_t* rgn, listnode_t* head);

// lock the region globally
void region_lock(void);

// unlock the region globally
void region_unlock(void);

// create a region
region_t* region_create(void);

// free / release a region
void region_free(region_t* rgn);

// add a visible view's clint area to a region
int region_add_view_area(struct view* vi, region_t* rgn);

// add a rect to a region
int region_addrect(region_t* rl, int left, int top, int width, int height);

// subtract a rect from region
void region_subtract_rect(region_t* rgn, int left, int top, int width, int height);

// normalize the region to view's coordinate system
void region_normalize(struct view* vi, region_t* rgn);

// exported functions
VISMGR_EXPORT_API int region_getrect(region_t* rl, rect_t* r);

#ifdef __cplusplus
} // extern "C"
#endif
#endif	// __C_VIEWS_RECT_H__
/* EOF */
